<!-- views/crawler/TaskPage.vue -->
<template>
  <div class="crawler-task-page">
    <el-card class="statistics-card">
      <el-row :gutter="20">
        <el-col :span="8">
          <el-statistic title="总任务数" :value="statistics?.totalTasks">
            <template #suffix>个</template>
          </el-statistic>
        </el-col>
        <el-col :span="8">
          <el-statistic title="成功任务" :value="statistics?.successTasks">
            <template #suffix>个</template>
          </el-statistic>
        </el-col>
        <el-col :span="8">
          <el-statistic title="总文章数" :value="statistics?.totalArticles">
            <template #suffix>篇</template>
          </el-statistic>
        </el-col>
      </el-row>
    </el-card>

    <el-card class="task-card">
      <!-- 批量操作按钮 -->
      <div class="batch-operations">
        <el-button type="danger" :disabled="!selectedTasks.length" @click="handleBatchDelete">
          批量删除
        </el-button>
        <el-button type="primary" @click="showCreateDialog">
          创建任务
        </el-button>
        <el-tag v-if="selectedTasks.length" type="info">
          已选择 {{ selectedTasks.length }} 项
        </el-tag>
      </div>

      <el-form :inline="true" class="search-form">
        <el-form-item label="数据源">
          <el-select v-model="searchForm.source" placeholder="选择数据源" clearable style="width: 160px" @change="handleSearchSourceChange">
            <el-option label="SoccerOdd" value="soccerodd" />
            <el-option label="FreeSuperTips" value="freesupertips" />
            <el-option label="ESPN" value="espn" />
          </el-select>
        </el-form-item>
        <el-form-item label="分类" v-if="searchForm.source">
          <!-- ESPN的分类选择 -->
          <el-cascader
              v-if="searchForm.source === 'espn'"
              v-model="searchForm.category"
              :options="espnCategories"
              :props="{
          checkStrictly: true,
          label: 'name',
          value: 'code',
          emitPath: false
        }"
              placeholder="选择ESPN分类"
              clearable
              style="width: 240px;"
          />
          <!-- SoccerOdd和FreeSuperTips不需要选择分类 -->
          <el-tag v-else>{{ searchForm.source }}</el-tag>
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker
              v-model="searchForm.dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>

      <el-table
          v-loading="loading"
          :data="tasks?.records"
          style="width: 100%"
          @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="taskId" label="任务ID" width="180" />
        <el-table-column prop="source" label="数据源" width="120" />
        <el-table-column prop="category" label="分类" width="100" />
        <el-table-column prop="startTime" label="开始时间" width="180" />
        <el-table-column prop="endTime" label="结束时间" width="180" />
        <el-table-column prop="status" label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)">
              {{ row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150">
          <template #default="{ row }">
            <el-button
                link
                type="primary"
                @click="showTaskDetail(row.taskId)"
            >
              查看详情
            </el-button>
            <el-popconfirm
                title="确定要删除这个任务吗？"
                @confirm="handleDelete(row.taskId)"
            >
              <template #reference>
                <el-button link type="danger">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <el-empty
          v-if="!loading && tasks.total === 0"
          description="暂无数据"
      >{{tasks.records}}
      </el-empty>

      <div class="pagination">
        <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :total="tasks?.total"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 创建任务对话框 -->
    <el-dialog
        v-model="createDialogVisible"
        title="创建爬虫任务"
        width="500px"
    >
      <el-form
          ref="createFormRef"
          :model="createForm"
          :rules="createRules"
          label-width="100px"
      >
        <el-form-item label="数据源" prop="source">
          <el-select v-model="createForm.source" placeholder="选择数据源" @change="handleCreateSourceChange">
            <el-option label="SoccerOdd" value="soccerodd" />
            <el-option label="FreeSuperTips" value="freesupertips" />
            <el-option label="ESPN" value="espn" />
          </el-select>
        </el-form-item>

        <!-- ESPN分类选择 -->
        <el-form-item
            v-if="createForm.source === 'espn'"
            label="ESPN分类"
            prop="categoryId"
        >
          <el-cascader
              v-model="createForm.categoryId"
              :options="espnCategories"
              :props="{
        checkStrictly: true,
        label: 'name',
        value: 'id',
        emitPath: false
      }"
              placeholder="请选择分类"
              clearable
              class="category-select"
              @change="handleCategoryChange"
          />
        </el-form-item>

        <el-form-item label="文章数量" prop="targetCount">
          <el-input-number
              v-model="createForm.targetCount"
              :min="1"
              :max="100"
              controls-position="right"
          />
        </el-form-item>

        <!-- 段落数量，仅当选择 ESPN 时显示 -->
        <el-form-item
            v-if="createForm.source === 'espn'"
            label="段落数量"
            prop="paragraphCount"
        >
          <el-input-number
              v-model="createForm.paragraphCount"
              :min="1"
              :max="10"
              controls-position="right"
          />
        </el-form-item>
      </el-form>
      <template #footer>
    <span class="dialog-footer">
      <el-button @click="createDialogVisible = false">取消</el-button>
      <el-button type="primary" @click="handleCreateTask" :loading="loading">
        确定
      </el-button>
    </span>
      </template>
    </el-dialog>

    <!-- 批量删除确认对话框 -->
    <el-dialog
        v-model="batchDeleteDialogVisible"
        title="批量删除确认"
        width="400px"
    >
      <p>确定要删除选中的 {{ selectedTasks.length }} 个任务吗？</p>
      <template #footer>
      <span class="dialog-footer">
        <el-button @click="batchDeleteDialogVisible = false">取消</el-button>
        <el-button type="danger" @click="confirmBatchDelete" :loading="batchDeleteLoading">
          确定删除
        </el-button>
      </span>
      </template>
    </el-dialog>

    <!-- 任务详情对话框 -->
    <el-dialog
        v-model="detailDialogVisible"
        title="任务详情"
        width="800px"
    >
      <el-descriptions v-if="currentTask" :column="2" border>
        <el-descriptions-item label="任务ID">
          {{ currentTask.taskId }}
        </el-descriptions-item>
        <el-descriptions-item label="数据源">
          {{ currentTask.source }}
        </el-descriptions-item>
        <el-descriptions-item label="开始时间">
          {{ currentTask.startTime }}
        </el-descriptions-item>
        <el-descriptions-item label="结束时间">
          {{ currentTask.endTime }}
        </el-descriptions-item>
        <el-descriptions-item label="目标数量">
          {{ currentTask.targetCount }}
        </el-descriptions-item>
        <el-descriptions-item label="成功数量">
          {{ currentTask.success }}
        </el-descriptions-item>
        <el-descriptions-item label="失败数量">
          {{ currentTask.failed }}
        </el-descriptions-item>
        <el-descriptions-item label="执行时长">
          {{ currentTask.duration }}ms
        </el-descriptions-item>
      </el-descriptions>

      <el-collapse v-if="currentTask?.errors?.length">
        <el-collapse-item title="错误信息">
          <el-alert
              v-for="(error, index) in currentTask.errors"
              :key="index"
              :title="error"
              type="error"
              show-icon
          />
        </el-collapse-item>
      </el-collapse>
    </el-dialog>
  </div>
</template>

<script setup>
import {onMounted, ref} from 'vue'
import {useCrawlerStore} from '@/stores/crawler'
import {ElMessage} from 'element-plus'
import {storeToRefs} from 'pinia'
import {getCategoryTree} from "@/api/category.js";

const store = useCrawlerStore()

// 搜索表单
// 搜索表单 - 完善初始值
const searchForm = ref({
  source: '',
  scheduled: null,
  dateRange: [] // 添加时间范围搜索
})

const selectedTasks = ref([])
const batchDeleteDialogVisible = ref(false)
const batchDeleteLoading = ref(false)

// 分页
const currentPage = ref(1)
const pageSize = ref(10)

// 创建任务表单
const createFormRef = ref(null)
const createDialogVisible = ref(false)
const createForm = ref({
  source: '',
  targetCount: 10,
  categoryId: null,    // 用于存储选中的分类ID
  category: '',  // ESPN 分类
  paragraphCount: 1,  // ESPN 段落数量
})

// ESPN分类选项
const espnCategories = ref([])
const soccerOddCategories = ref([])
const freeSuperTipsCategories = ref([])

// 加载ESPN分类数据
const loadESPNCategories = async () => {
  try {
    const { data } = await getCategoryTree('crawler')  // 获取爬虫分类树
    // 找到ESPN分类及其子分类
    const espnCategory = data.find(cat => cat.code === 'ESPN')
    if (espnCategory) {
      espnCategories.value = [espnCategory]
    }
    const soccerOddCategory = data.find(cat => cat.code === 'SOCCER_ODD')
    if (soccerOddCategory) {
      soccerOddCategories.value = [soccerOddCategory]
    }
    const freeSuperTipsCategory = data.find(cat => cat.code === 'FREE_SUPER_TIPS')
    if (freeSuperTipsCategory) {
      freeSuperTipsCategories.value = [freeSuperTipsCategory]
    }
  } catch (error) {
    ElMessage.error('获取分类失败')
  }
}

// 分类选择改变的处理
const handleCategoryChange = (value) => {
  if (value) {
    // 从分类树中找到选中的分类节点
    const findCategory = (categories, id) => {
      for (const cat of categories) {
        if (cat.id === id) return cat
        if (cat.children) {
          const found = findCategory(cat.children, id)
          if (found) return found
        }
      }
      return null
    }

    const selectedCategory = findCategory(espnCategories.value, value)
    if (selectedCategory) {
      createForm.value.categoryId = selectedCategory.id     // 保存分类ID
      // 从code中提取category，如 "ESPN_SOCCER" -> "soccer"
      createForm.value.category = selectedCategory.code.toLowerCase().split('_')[1]
    }
  } else {
    createForm.value.category = ''
    createForm.value.categoryId = null
  }
}

// 搜索表单数据源变化处理
const handleSearchSourceChange = (value) => {
  searchForm.category = null  // 清空分类选择
}

// 创建表单数据源变化处理
const handleCreateSourceChange = (value) => {
  createForm.value.categoryId = null
  createForm.value.category = ''

  if (value === 'soccerodd') {
    // 找到对应的分类ID
    createForm.value.categoryId = soccerOddCategories.value[0].id
  }
  if (value === 'freesupertips') {
    // 找到对应的分类ID
    createForm.value.categoryId = freeSuperTipsCategories.value[0].id
  }
  // 如果不是ESPN，重置段落数量
  if (value !== 'espn') {
    createForm.paragraphCount = 1
  }
}

// 完善表单验证规则
const createRules = {
  source: [
    { required: true, message: '请选择数据源', trigger: 'change' }
  ],
  targetCount: [
    { required: true, message: '请输入目标数量', trigger: 'blur' },
    { type: 'number', min: 1, max: 100, message: '数量必须在1-100之间', trigger: 'blur' }
  ],
  category: [
    {
      required: true,
      message: '请选择分类',
      trigger: 'change',
      // 只有在选择ESPN时才验证
      validator: (rule, value, callback) => {
        if (createForm.value.source === 'espn' && !value) {
          callback(new Error('请选择ESPN分类'))
        } else {
          callback()
        }
      }
    }
  ],
  paragraphCount: [
    { required: true, message: '请输入段落数量', trigger: 'blur' },
    { type: 'number', min: 1, max: 100, message: '数量必须在1-100之间', trigger: 'blur' }
  ]
}

// 详情弹窗
const detailDialogVisible = ref(false)

// 生命周期钩子
onMounted(async () => {
  await Promise.all([
    fetchTaskList(),
    loadESPNCategories(),
    store.fetchStatistics()
  ])
})

// 方法
const fetchTaskList = async () => {
  const params = {
    current: currentPage.value,
    size: pageSize.value,
    ...searchForm.value
  }
  await store.fetchTasks(params)
}

// 完善搜索方法
const handleSearch = async () => {
  currentPage.value = 1
  const params = {
    current: currentPage.value,
    size: pageSize.value,
    ...searchForm.value,
    startTime: searchForm.value.dateRange?.[0],
    endTime: searchForm.value.dateRange?.[1]
  }
  try {
    await store.fetchTasks(params)
  } catch (error) {
    ElMessage.error('搜索失败：' + error.message)
  }
}

// 完善重置方法
const resetSearch = () => {
  searchForm.value = {
    source: '',
    scheduled: null,
    keyword: '',
    dateRange: []
  }
  handleSearch()
}

const handleSizeChange = (val) => {
  pageSize.value = val
  fetchTaskList()
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  fetchTaskList()
}

const showCreateDialog = () => {
  createForm.value = {
    source: '',
    category: '',
    targetCount: 10
  }
  createDialogVisible.value = true
}

// 完善创建任务方法
const handleCreateTask = async () => {
  if (!createFormRef.value) return

  await createFormRef.value.validate(async (valid) => {
    if (valid) {
      const params = {
        source: createForm.value.source,
        targetCount: createForm.value.targetCount
      }


      // 如果是ESPN，添加分类和段落数量
      if (createForm.value.source === 'espn') {
        params.category = createForm.value.category
        params.categoryId = createForm.value.categoryId
        params.paragraphCount = createForm.value.paragraphCount
      }else {
        params.category = createForm.value.source
        params.categoryId = createForm.value.categoryId
      }

      console.log(params)

      try {
        await store.createTask(params)
        ElMessage.success('任务创建成功')
        createDialogVisible.value = false
        await fetchTaskList()
        await store.fetchStatistics()
      } catch (error) {
        ElMessage.error('任务创建失败：' + error.message)
      }
    }
  })
}

const showTaskDetail = async (taskId) => {
  try {
    await store.getTaskDetail(taskId)
    detailDialogVisible.value = true
  } catch (error) {
    ElMessage.error('获取任务详情失败：' + error.message)
  }
}

const getStatusType = (status) => {
  const map = {
    'SUCCESS': 'success',
    'FAILED': 'danger',
    'RUNNING': 'warning',
    'PENDING': 'info'
  }
  return map[status] || 'info'
}

// 处理表格选择变化
const handleSelectionChange = (selection) => {
  selectedTasks.value = selection
}

// 单个删除
const handleDelete = async (taskId) => {
  try {
    await store.deleteTaskById(taskId)
    ElMessage.success('删除成功')
    await fetchTaskList()
    await store.fetchStatistics() // 更新统计数据
  } catch (error) {
    ElMessage.error('删除失败：' + error.message)
  }
}

// 批量删除
const handleBatchDelete = () => {
  if (selectedTasks.value.length === 0) {
    ElMessage.warning('请先选择要删除的任务')
    return
  }
  batchDeleteDialogVisible.value = true
}

const confirmBatchDelete = async () => {
  try {
    batchDeleteLoading.value = true
    const ids = selectedTasks.value.map(task => task.taskId)
    await store.batchDeleteTasks(ids)
    ElMessage.success('批量删除成功')
    batchDeleteDialogVisible.value = false
    await fetchTaskList()
    await store.fetchStatistics() // 更新统计数据
  } catch (error) {
    ElMessage.error('批量删除失败：' + error.message)
  } finally {
    batchDeleteLoading.value = false
  }
}

// 计算属性
const { tasks, loading, currentTask, statistics } = storeToRefs(store)
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.left-operations {
  display: flex;
  align-items: center;
  gap: 16px;
}

.selection-count {
  color: #606266;
  font-size: 14px;
}

.batch-operations {
  margin-bottom: 16px;
}

.crawler-task-page {
  padding: 20px;
}

.statistics-card {
  margin-bottom: 20px;
}

.task-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-form {
  margin-bottom: 20px;
}

.pagination {
  margin-top: 20px;
  text-align: right;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>